﻿using System;
using System.ComponentModel.Composition;
using System.Windows.Media.Imaging;
using Microsoft.WebMatrix.Extensibility;
using System.IO;
using System.Text;
using System.Collections.Generic;
using PenguinPublishNS.Models;
using PenguinPublishNS.Views;

namespace PenguinPublishNS
{
    /// <summary>
    /// A  WebMatrix extension for publishing website via SFTP to LAMP servers
    /// </summary>
    // conditionally loads based on:
    // WebMx project will be PHP, HTML, Node type
    // Look for files: index.php, index.html, package.json, app.js, server.js

    [Export(typeof(Extension))]
    public class PenguinPublish : Extension
    {

        //--------------------------------------------------------------------------
        //
        //	Variables
        //
        //--------------------------------------------------------------------------

        #region Variables

        /// <summary>
        /// Stores references to the icons
        /// </summary>
        private readonly BitmapImage _sftpImageSmall = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/sftp_16x16.png", UriKind.Absolute));
        private readonly BitmapImage _sftpImageLarge = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/sftp_32x32.png", UriKind.Absolute));
        private readonly BitmapImage _sftpGroupImage = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/sftp_32x32.png", UriKind.Absolute));
        private readonly BitmapImage _smallSvrImage = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/16x16web_secure.png", UriKind.Absolute));
        private readonly BitmapImage _largeSvrImage = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/32x32_web_secure.png", UriKind.Absolute));
        private readonly BitmapImage _previewImage = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/32x32_preview.png", UriKind.Absolute));
        private readonly BitmapImage _settingsImageSmall = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/16x16_folder_linux.png", UriKind.Absolute));
        private readonly BitmapImage _settingsImageLarge = new BitmapImage(new Uri("pack://application:,,,/PenguinPublish;component/Images/32x32_folder_linux.png", UriKind.Absolute));

        /// <summary>
        /// Stores a reference to the WebMatrix host interface.
        /// </summary>
        //private IWebMatrixHost _webMatrixHost;

        /// <summary>       
        /// determines if the current site is php or not
        /// </summary>
        private bool _isPhpSite;

        /// <summary>
        /// PHP control ribbon group - is there a way to grab existing ones?
        /// </summary>
        private RibbonGroup _ribbonGroup;

        public static string dataPath; // used for writing all files from PenguinPublish
        public static string webFilesPath; // used for recursive listing of website files and directories
        public static bool isNetworkConnected; // used for initial detection of network connectivity: top of State chain

        private StringBuilder sb = new StringBuilder();
        private List<WebFile> listFileAndDirs = new List<WebFile>();

        #endregion

        //--------------------------------------------------------------------------
        //
        //	Constructors
        //
        //--------------------------------------------------------------------------

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the PenguinPublish class.
        /// </summary>
        public PenguinPublish()
            : base("PenguinPublish")
        {
        }

        /// <summary>
        /// Called to initialize the extension.
        /// </summary>
        /// <param name="host">WebMatrix host interface.</param>
        /// <param name="initData">Extension initialization data.</param>
        ///         
        public static IWebMatrixHost _webMatrixHost
        {
            get;
            private set;
        }

        protected override void Initialize(IWebMatrixHost host, ExtensionInitData initData)
        {
            _webMatrixHost = host;

            host.WorkspaceChanged += new EventHandler<WorkspaceChangedEventArgs>(WebMatrixHost_WorkspaceChanged);
            host.WebSiteChanged += new EventHandler<EventArgs>(WebMatrixHost_WebSiteChanged);

            // Add a simple button to the Ribbon
            initData.RibbonItems.Add(
                _ribbonGroup = new RibbonGroup(
                    "Penguin Publish",
                    new RibbonItem[]
                        {
                            new RibbonButton(
                        "Preview & Publish",
                        new DelegateCommand(PublishRibbonButtonInvoke),
                        null,
                        _sftpImageSmall,
                        _sftpImageLarge),
                        //    new RibbonButton(
                        //"Remote Connect",
                        //new DelegateCommand(RemoteRibbonButtonInvoke),
                        //null,
                        //null as BitmapImage,
                        //_previewImage),
                            new RibbonButton(
                        "Setup Server",
                        new DelegateCommand(SetupServerRibbonButtonInvoke),
                        null,
                        _smallSvrImage,
                        _largeSvrImage) ,
                        //    new RibbonButton(
                        //"Options",
                        //new DelegateCommand(OptionsRibbonButtonInvoke),
                        //null,
                        //_settingsImageSmall,
                        //_settingsImageLarge),
                        }, _sftpGroupImage));


        }

        #endregion

        //--------------------------------------------------------------------------
        //
        //	Event Handlers
        //
        //--------------------------------------------------------------------------      

        #region Event_Handlers

        /// Called when the Ribbon button is invoked.

        private void OptionsRibbonButtonInvoke(object parameter)
        {
            var dialog = new SetOptions();
            _webMatrixHost.ShowDialog("Set global options for Penguin Publish", dialog, DialogSize.Medium);
        }

        private void RemoteRibbonButtonInvoke(object parameter)
        {
            var dialog = new HostRemoteDir();
            _webMatrixHost.ShowDialog("Connect to remote host to review website files", dialog, DialogSize.Large);
        }

        private void SetupServerRibbonButtonInvoke(object parameter)
        {
            var dialog = new HostSettings();
            _webMatrixHost.ShowDialog("New/Update Host Setting (more than 1 host is permitted)", dialog, DialogSize.Large);
        }

        private void PublishRibbonButtonInvoke(object parameter)
        {
            var dialog = new WebFilesList();
            _webMatrixHost.ShowDialog("Compare local website files to published files snapshot", dialog, DialogSize.Large);
        }
        /// <summary>
        /// Called when the WebMatrixHost's WorkspaceChanged event fires.
        /// </summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event arguments.</param>
        private void WebMatrixHost_WorkspaceChanged(object sender, WorkspaceChangedEventArgs e)
        {
            _ribbonGroup.IsVisible = e.NewWorkspace is IEditorWorkspace & _isPhpSite;
        }

        /// <summary>
        /// Called when the WebMatrixHost's WorkspaceChanged event fires.
        /// </summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event arguments.</param>
        private void WebMatrixHost_WebSiteChanged(object sender, EventArgs e)
        {
            _isPhpSite = IsPhpProject();

            if (_isPhpSite)
            {
                // Set up our path for saving preferences, snapshots and host settings
                dataPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\IISExpress\config\PublishUI\" + _webMatrixHost.WebSite.Name;
                webFilesPath = _webMatrixHost.WebSite.Path;
                if (!File.Exists(dataPath + @"\dataHostSetting.json"))
                {
                    File.Create(dataPath + @"\dataHostSetting.json");
                }
            }

        }
        #endregion

        //--------------------------------------------------------------------------
        //
        //	Methods
        //
        //--------------------------------------------------------------------------

        #region Methods

        /// determine if the current project is likely to be PHP
        /// or is plain HTML, or is Node.js (index.html, app.js, server.js, package.json)

        protected bool IsPhpProject()  // TODO: or Node or HTML  2-22-13 WCD-added index.html to activate in 2nd project type
        {
            // for now depend on the index.php file existing
            if (_webMatrixHost.WebSite != null && !String.IsNullOrEmpty(_webMatrixHost.WebSite.Path))
            {
                var path = _webMatrixHost.WebSite.Path;
                if (File.Exists(path + @"\index.php") || File.Exists(path + @"\index.html"))
                {
                    return true;
                }
            }
            return false;
        }

        //protected void WriteHashCsvFile(string myFile, string csv)
        //{
        //    File.WriteAllText(myFile, csv);
        //}

        //protected string getMD5hash(string fPath)
        //{
        //    byte[] computedHash = new MD5CryptoServiceProvider().ComputeHash(File.ReadAllBytes(@fPath));
        //    var sBuilder = new StringBuilder();
        //    foreach (byte b in computedHash)
        //    {
        //        sBuilder.Append(b.ToString("x2").ToLower());
        //    }
        //    return sBuilder.ToString();
        //}

        //protected void DirSearch(string dir)
        //{
        //    foreach (string f in Directory.GetFiles(dir))
        //    {
        //        string fixPath = f.Replace(@"\", "/");
        //        sb.AppendFormat("{0},{1}\n", fixPath, getMD5hash(f));
        //    }
        //    foreach (string d in Directory.GetDirectories(dir))
        //    {
        //        string fixPath = d.Replace(@"\", "/");
        //        sb.AppendLine(fixPath);
        //        DirSearch(d);
        //    }
        //}

        //protected void ReadFilesAndDirs(string dir)
        //{
        //    foreach (string f in Directory.GetFiles(dir))
        //    {
        //        string fixPath = f.Replace(@"\", "/");
        //        var wf = new WebFile();
        //        wf.filepath = fixPath;
        //        wf.filehash = getMD5hash(f);
        //        listFileAndDirs.Add(wf);
        //    }
        //    foreach (string d in Directory.GetDirectories(dir))
        //    {
        //        string fixPath = d.Replace(@"\", "/");
        //        var wf = new WebFile();
        //        wf.filepath = fixPath;
        //        wf.filehash = d.GetHashCode().ToString();  //Cannot run ComputeHash, so just use this function
        //        listFileAndDirs.Add(wf);
        //        ReadFilesAndDirs(d);
        //    }

        //}


        #endregion

    }
}
